#include "config.h"

#include <stdint.h>
#include <unistd.h>

#define DBG_SUBSYS S_LIBTASK

#include "timer.h"
#include "system.h"
#include "utils.h"
#include "etcd.h"


typedef struct {
        worker_handler_t worker_handler;
        uint64_t interval;
        int inited;
        char name[MAX_NAME_LEN];
        func_int1_t handler;
} etcd_task_t;

static etcd_task_t __pool_remove_task;


static int __task_pool_remove(void *arg1, void *arg2)
{
        int ret;
        const char *pool_name = arg1;
        (void) arg2;

        DINFO("pool %s\n", pool_name);

        ret = task_pool_remove(pool_name);
        if (unlikely(ret)) {
                if (ret == ENOKEY) {
                } else {
                        GOTO(err_ret, ret);
                }
        }

        ret = etcd_del("task/poolremove", pool_name);
        if (unlikely(ret))
                GOTO(err_ret, ret);

        return 0;
err_ret:
        return ret;
}

STATIC int __etcd_task_worker(void *_args)
{
        int ret;
        etcd_task_t *task = _args;

        YASSERT(task->handler != NULL);

        if (task->inited == 0) {
                DINFO("etcd task stoped\n");
                return 0;
        }
        
        ret = etcd_task_iterator(task->name, task->handler, task);
        if (unlikely(ret)) {
                DBUG("task %s ret %d\n", task->name, ret);
        }

        ret = timer1_settime(&task->worker_handler, task->interval);
        if (unlikely(ret)) {
                DERROR("settime error ret %d\n", ret);
                YASSERT(0);
        }

        return ret;
}

static int __etcd_task_start(etcd_task_t *task)
{
        int ret;

        DINFO("etcd task %s start, interval %ju\n", task->name, task->interval);

        YASSERT(!task->inited);

        ret = timer1_create(&task->worker_handler, task->name, __etcd_task_worker, task);
        if (unlikely(ret)) {
                DERROR("ret %d\n", ret);
                GOTO(err_ret, ret);
        }

        ret = timer1_settime(&task->worker_handler, task->interval);
        if (unlikely(ret)) {
                DERROR("ret %d\n", ret);
                GOTO(err_ret, ret);
        }

        task->inited = 1;

        return 0;
err_ret:
        return ret;
}

int etcd_task_pool_remove()
{
        int ret;
        etcd_task_t *task = &__pool_remove_task;

        strcpy(task->name, "poolremove");
        task->inited = 0;
        task->interval = USEC_PER_MIN;
        task->handler = __task_pool_remove;

        ret = __etcd_task_start(task);
        if (unlikely(ret)) {
                DERROR("flat_bh_start fail!!! ret:%d\n", ret);
                YASSERT(0);
        }

        return 0;
}

int etcd_task_start()
{
        etcd_task_pool_remove();

        return 0;
}

void etcd_task_stop()
{
        __pool_remove_task.inited = 0;
}
